#include "SceneGenerator.h"
#include "Poligon3DSceneNode.h"
#include "TextSceneNode.h"
#include "LightSceneNode.h"
#include "SphereSceneNode.h"
#include "ViewerCameraSceneNode.h"
#include "2DCameraSceneNode.h"
#include "2DSpriteSceneNode.h"
#include "../include/PowerLibraryEngine.h"

#define Common3D	if (!parent) parent = Default3DParent;if (!parent) parent = SceneManager;
#define Common2D	if (!parent) parent = Default2DParent;if (!parent) parent = SceneManager;

CSceneGenerator::CSceneGenerator():ISceneGenerator(),Default3DParent(NULL),Default2DParent(NULL)
{
}

CSceneGenerator::~CSceneGenerator()
{
}

void CSceneGenerator::SetDefaultScene3DParent(ISceneNode *newdp)
{
	Default3DParent = newdp;
	if (!Default3DParent)
		Default3DParent = SceneManager;
}

void CSceneGenerator::SetDefaultScene2DParent(ISceneNode *newdp)
{
	Default2DParent = newdp;
	if (!Default2DParent)
		Default2DParent = SceneManager;
}

ISceneNode *CSceneGenerator::GetNewEmptySceneNode(ISceneNodeReceiveParams)
{
	return NULL;
}

I2DCameraSceneNode *CSceneGenerator::GetNew2DCameraSceneNode(ISceneNodeReceiveParams)
{
	Common2D;

	return new C2DCameraSceneNode(ISceneNodeBasicParams);
}

I3DCameraSceneNode *CSceneGenerator::GetNew3DCameraSceneNode(vPos angle,vPos aspect,vector3dvpos lookat,vPos znear,
																   vPos zfar,vector3dvpos vup,
																   ISceneNodeReceiveParams)
{
	Common3D;

	return new CViewerCameraSceneNode(angle,aspect,lookat,znear,zfar,vup,ISceneNodeBasicParams);
}

ILightSceneNode *CSceneGenerator::GetNewLightSceneNode(IMaterial mat,vector3df32 nspotd,f32 spotco,ISceneNodeReceiveParams)
{
	Common3D;

	return new CLightSceneNode(mat,nspotd,spotco,ISceneNodeBasicParams);
}

IDrawableSceneNode *CSceneGenerator::GetNewCubeSceneNode(vector3dvpos Len,ISceneNodeReceiveParams)
{
	Common3D;

	IPoligon3D pol(4);
	pol.AddVector((vPos)(-1.0 * Len.X / 2.0),(vPos)(-1.0 * Len.Y / 2.0),(vPos)(-1.0 * Len.Z / 2.0));
	pol.AddVector((vPos)(Len.X / 2.0),(vPos)(-1.0 * Len.Y / 2.0),(vPos)(-1.0 * Len.Z / 2.0));
	pol.AddVector((vPos)(Len.X / 2.0),(vPos)(Len.Y / 2.0),(vPos)(-1.0 * Len.Z / 2.0));
	pol.AddVector((vPos)(-1.0 * Len.X / 2.0),(vPos)(Len.Y / 2.0),(vPos)(-1.0 * Len.Z / 2.0));
	return GetNewPoligon3DSceneNode(vector3dvpos(0.0,0.0,1.0),&pol,0,ISceneNodeBasicParams);
}

IDrawableSceneNode *CSceneGenerator::GetNewPoligon3DSceneNode(vector3dvpos Len,IPoligon3D *PolBase,std::vector<bool> *HideFace,ISceneNodeReceiveParams)
{
	Common3D;

	return new CPoligon3DSceneNode(this,Len,PolBase,HideFace,ISceneNodeBasicParams);
}

ITextSceneNode *CSceneGenerator::GetNewTextNode(IFont *fnt,stringc Text,AlignementX ax,AlignementY ay,vector2dvpos nSpace,vPos nPoints,ISceneNodeReceiveParams)
{
	Common2D;

	return new CTextSceneNode(fnt,Text,ax,ay,nSpace,nPoints,ISceneNodeBasicParams);
}

I2DSpriteSceneNode *CSceneGenerator::GetNew2DSpriteSceneNode(ITexture *Tex,ISceneNodeReceiveParams)
{
	Common2D;

	C2DSpriteSceneNode *Temp = new C2DSpriteSceneNode(ISceneNodeBasicParams);
	Temp->SetTextures(Tex);
	return Temp;
}

IDrawableSceneNode *CSceneGenerator::GetNewSphereSceneNode(vector3dvpos Radius,u32 Partitions,ISceneNodeReceiveParams)
{
	Common3D;

	return new CSphereSceneNode(this,Radius,Partitions,ISceneNodeBasicParams);
}

IDrawableFace *CSceneGenerator::GetNewQuadFace(IMaterial *Material,vector3dvpos *Vertexs)
{
	IDrawableFace	*de = new IDrawableFace(4);
	de->GetTCoord()->SetTextureCoordinatesStandard(TC_UP_DOWN);
	de->AddVector(Vertexs[0].X,Vertexs[0].Y,Vertexs[0].Z);
	de->AddVector(Vertexs[1].X,Vertexs[1].Y,Vertexs[1].Z);
	de->AddVector(Vertexs[2].X,Vertexs[2].Y,Vertexs[2].Z);
	de->AddVector(Vertexs[3].X,Vertexs[3].Y,Vertexs[3].Z);
//	de->UpdateMaterial(Material);
	de->UpdateNormal();

	return de;
}
